#if !defined( WEBBY_MESSAGE_HXX )
#define WEBBY_MESSAGE_HXX

#include <map>
#include <string>
#include <vector>
#include <stdio.h>
#include <stdlib.h>

#include <boost/shared_ptr.hpp>
#include <map>

#include <webby/config.hxx>

namespace webby 
{
	class Server;

	class Message
	{
	public:
		Message( unsigned short clientSocket ) : mSocket( clientSocket ) {}
		enum ResponseCode
		{
			OK = 200,
			NOTFOUND = 404
		};

		Message();
		virtual ~Message() {}
		virtual void doWork() = 0;
		static std::vector< std::string > parse( const std::string &s, const std::string &delimiter );	
		static boost::shared_ptr< std::map< std::string, std::string > > mMimeTypes;
	protected: 
		int mSocket;
		void outputHeaders( ResponseCode code, const std::string &MIMEType, unsigned int contentLength = 0 );
	};

	class ReadSocketMessage : public Message
	{
	public:
		ReadSocketMessage( boost::shared_ptr< Server > serverPtr, int readSocket ) : Message( readSocket), mServerPtr( serverPtr ) {}
		virtual void doWork();
	protected:
		std::map< std::string, std::string > mHeaders;

		void handleRequest();
		std::string getMIMETypeFromExtension( const std::string &extension );

		boost::shared_ptr<Server> mServerPtr;
	private:
		ReadSocketMessage() {}
	};

	class FastCGIOutputMessage : public Message
	{
	public:
		FastCGIOutputMessage( boost::shared_ptr< Server > serverPtr, char *content, unsigned int contentSize, int clientSocket ) : Message( clientSocket ), mServerPtr( serverPtr ), mContent( content ), mContentSize( contentSize) {}

		virtual void doWork();

		boost::shared_ptr< Server > mServerPtr;
		char *mContent;
		unsigned int mContentSize;

	private:
		FastCGIOutputMessage() {}
	};

	class BeginFastCGIMessage : public Message
	{
	public:
		BeginFastCGIMessage( boost::shared_ptr< Server > serverPtr, const std::string &extension, const std::string &script, int clientSocket) : 
			Message( clientSocket ), mServerPtr( serverPtr), mExt( extension ), mScript( script )
		{

		}

		virtual void doWork();

		boost::shared_ptr<Server> mServerPtr;
		std::string mExt;
		std::string mScript;
	private:
		BeginFastCGIMessage() {}
	};

}

#endif
